package com.xujie.sportsmeeting.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xujie.sportsmeeting.common.result.Result;
import com.xujie.sportsmeeting.dto.ScoreRecordDTO;
import com.xujie.sportsmeeting.entity.*;
import com.xujie.sportsmeeting.service.*;
import com.xujie.sportsmeeting.vo.CompetitionScoreVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.List;

/**
 * 比赛成绩管理控制器
 */
@Tag(name = "比赛成绩管理", description = "成绩录入、查询、排名管理接口")
@RestController
@RequestMapping("/scores")
@RequiredArgsConstructor
public class CompetitionScoreController {

    private final CompetitionScoreService competitionScoreService;
    private final CompetitionEventService competitionEventService;
    private final AthleteService athleteService;
    private final SysUserService sysUserService;
    private final JudgeService judgeService;

    @Operation(summary = "分页查询成绩记录")
    @GetMapping
    @PreAuthorize("hasAnyAuthority('score', 'system:user', 'judge', 'athlete')")
    public Result<Page<CompetitionScoreVO>> pageScores(
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "10") Long size,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Long eventId,
            @RequestParam(required = false) Long athleteId,
            @RequestParam(required = false) Integer isFinal) {
        
        // 获取当前登录用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        SysUser currentUser = sysUserService.findByUsername(username);
        
        // 检查用户角色，如果是运动员，只能查看自己的成绩
        List<String> roles = sysUserService.findRolesByUserId(currentUser.getId());
        boolean isAthlete = roles.contains("ATHLETE") || roles.contains("athlete");
        
        Page<CompetitionScore> page = new Page<>(current, size);
        LambdaQueryWrapper<CompetitionScore> wrapper = new LambdaQueryWrapper<>();
        
        // 如果是运动员角色，强制限制只查看自己的成绩
        if (isAthlete) {
            Athlete athlete = athleteService.findByUserId(currentUser.getId());
            if (athlete != null) {
                wrapper.eq(CompetitionScore::getAthleteId, athlete.getId());
            } else {
                // 如果找不到对应的运动员记录，返回空结果
                return Result.success(new Page<>(current, size, 0));
            }
        } else {
            // 非运动员用户的条件查询
            if (eventId != null) {
                wrapper.eq(CompetitionScore::getEventId, eventId);
            }
            if (athleteId != null) {
                wrapper.eq(CompetitionScore::getAthleteId, athleteId);
            }
        }
        
        if (isFinal != null) {
            wrapper.eq(CompetitionScore::getIsFinal, isFinal);
        }
        
        wrapper.eq(CompetitionScore::getStatus, 1)
               .orderByAsc(CompetitionScore::getRanking)
               .orderByDesc(CompetitionScore::getCreateTime);
        
        Page<CompetitionScore> result = competitionScoreService.page(page, wrapper);
        
        // 转换为VO
        Page<CompetitionScoreVO> voPage = new Page<>(result.getCurrent(), result.getSize(), result.getTotal());
        voPage.setRecords(result.getRecords().stream().map(score -> {
            CompetitionScoreVO vo = convertToVO(score);
            
            // 关键字过滤
            if (StringUtils.hasText(keyword)) {
                String searchText = (vo.getAthleteName() + vo.getStudentNumber() + 
                                   vo.getEventName() + vo.getDepartment()).toLowerCase();
                if (!searchText.contains(keyword.toLowerCase())) {
                    return null;
                }
            }
            
            return vo;
        }).filter(vo -> vo != null).toList());
        
        return Result.success(voPage);
    }

    @Operation(summary = "录入成绩")
    @PostMapping
    @PreAuthorize("hasAnyAuthority('score', 'judge', 'system:user')")
    public Result<Void> recordScore(@Valid @RequestBody ScoreRecordDTO scoreDTO) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        SysUser currentUser = sysUserService.findByUsername(username);
        
        CompetitionScore score = new CompetitionScore();
        BeanUtils.copyProperties(scoreDTO, score);
        score.setRecorderId(currentUser.getId());
        
        competitionScoreService.recordScore(score);
        return Result.success("成绩录入成功");
    }

    @Operation(summary = "批量录入成绩")
    @PostMapping("/batch")
    @PreAuthorize("hasAnyAuthority('score', 'judge', 'system:user')")
    public Result<Void> batchRecordScores(@Valid @RequestBody List<ScoreRecordDTO> scoreDTOs) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        SysUser currentUser = sysUserService.findByUsername(username);
        
        List<CompetitionScore> scores = scoreDTOs.stream().map(scoreDTO -> {
            CompetitionScore score = new CompetitionScore();
            BeanUtils.copyProperties(scoreDTO, score);
            score.setRecorderId(currentUser.getId());
            return score;
        }).toList();
        
        competitionScoreService.batchRecordScores(scores);
        return Result.success("批量录入成绩成功");
    }

    @Operation(summary = "更新成绩")
    @PutMapping("/{id}")
    @PreAuthorize("hasAnyAuthority('score', 'judge', 'system:user')")
    public Result<Void> updateScore(@PathVariable Long id, @Valid @RequestBody ScoreRecordDTO scoreDTO) {
        CompetitionScore existScore = competitionScoreService.getById(id);
        if (existScore == null) {
            return Result.error("成绩记录不存在");
        }
        
        CompetitionScore score = new CompetitionScore();
        BeanUtils.copyProperties(scoreDTO, score);
        score.setId(id);
        
        competitionScoreService.updateScore(score);
        return Result.success("成绩更新成功");
    }

    @Operation(summary = "删除成绩")
    @DeleteMapping("/{id}")
    @PreAuthorize("hasAnyAuthority('score', 'system:user')")
    public Result<Void> deleteScore(@PathVariable Long id) {
        competitionScoreService.deleteScore(id);
        return Result.success("成绩删除成功");
    }

    @Operation(summary = "根据项目查询成绩列表")
    @GetMapping("/event/{eventId}")
    @PreAuthorize("hasAnyAuthority('score', 'system:user', 'judge', 'athlete')")
    public Result<List<CompetitionScoreVO>> getEventScores(
            @PathVariable Long eventId,
            @RequestParam(required = false) Integer isFinal) {
        
        List<CompetitionScore> scores = competitionScoreService.getEventScores(eventId, isFinal);
        List<CompetitionScoreVO> voList = scores.stream().map(this::convertToVO).toList();
        
        return Result.success(voList);
    }

    @Operation(summary = "根据运动员查询成绩列表")
    @GetMapping("/athlete/{athleteId}")
    @PreAuthorize("hasAnyAuthority('score', 'system:user', 'judge', 'athlete')")
    public Result<List<CompetitionScoreVO>> getAthleteScores(@PathVariable Long athleteId) {
        // 如果是运动员角色，只能查看自己的成绩
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        SysUser currentUser = sysUserService.findByUsername(username);
        
        List<String> roles = sysUserService.findRolesByUserId(currentUser.getId());
        if (roles.contains("ATHLETE")) {
            Athlete athlete = athleteService.findByUserId(currentUser.getId());
            if (athlete == null || !athlete.getId().equals(athleteId)) {
                return Result.error("只能查看自己的成绩");
            }
        }
        
        List<CompetitionScore> scores = competitionScoreService.getAthleteScores(athleteId);
        List<CompetitionScoreVO> voList = scores.stream().map(this::convertToVO).toList();
        
        return Result.success(voList);
    }

    @Operation(summary = "获取项目前N名成绩")
    @GetMapping("/event/{eventId}/top")
    @PreAuthorize("hasAnyAuthority('score', 'system:user', 'judge', 'athlete')")
    public Result<List<CompetitionScoreVO>> getTopScores(
            @PathVariable Long eventId,
            @RequestParam(defaultValue = "8") Integer topN,
            @RequestParam(required = false) Integer isFinal) {
        
        List<CompetitionScore> scores = competitionScoreService.getTopScores(eventId, topN, isFinal);
        List<CompetitionScoreVO> voList = scores.stream().map(this::convertToVO).toList();
        
        return Result.success(voList);
    }

    @Operation(summary = "重新计算项目排名")
    @PostMapping("/event/{eventId}/rankings")
    @PreAuthorize("hasAnyAuthority('score', 'system:user')")
    public Result<Void> calculateRankings(
            @PathVariable Long eventId,
            @RequestParam(required = false) Integer isFinal) {
        
        competitionScoreService.calculateRankings(eventId, isFinal);
        return Result.success("排名计算完成");
    }

    @Operation(summary = "根据ID查询成绩详情")
    @GetMapping("/{id}")
    @PreAuthorize("hasAnyAuthority('score', 'system:user', 'judge', 'athlete')")
    public Result<CompetitionScoreVO> getScore(@PathVariable Long id) {
        CompetitionScore score = competitionScoreService.getById(id);
        if (score == null) {
            return Result.error("成绩记录不存在");
        }
        
        CompetitionScoreVO vo = convertToVO(score);
        return Result.success(vo);
    }

    @Operation(summary = "获取成绩统计信息")
    @GetMapping("/statistics")
    @PreAuthorize("hasAnyAuthority('score', 'system:user', 'judge')")
    public Result<Object> getScoreStatistics(
            @RequestParam(required = false) Long eventId,
            @RequestParam(required = false) String department,
            @RequestParam(required = false) String className) {
        
        // TODO: 实现统计逻辑
        Object statisticsData = "统计功能待实现";
        return Result.success(statisticsData);
    }

    /**
     * 转换为VO对象
     */
    private CompetitionScoreVO convertToVO(CompetitionScore score) {
        CompetitionScoreVO vo = new CompetitionScoreVO();
        BeanUtils.copyProperties(score, vo);
        
        // 查询项目信息
        CompetitionEvent event = competitionEventService.getById(score.getEventId());
        if (event != null) {
            vo.setEventName(event.getEventName());
            vo.setEventCode(event.getEventCode());
        }
        
        // 查询运动员信息
        Athlete athlete = athleteService.getById(score.getAthleteId());
        if (athlete != null) {
            vo.setAthleteName(athlete.getRealName());
            vo.setStudentNumber(athlete.getStudentNumber());
            vo.setDepartment(athlete.getDepartment());
            vo.setClassName(athlete.getClassName());
        }
        
        // 查询记录员信息
        if (score.getRecorderId() != null) {
            SysUser recorder = sysUserService.getById(score.getRecorderId());
            if (recorder != null) {
                vo.setRecorderName(recorder.getRealName());
            }
        }
        
        // 查询裁判员信息
        if (score.getJudgeId() != null) {
            Judge judge = judgeService.getById(score.getJudgeId());
            if (judge != null) {
                vo.setJudgeName(judge.getRealName());
            }
        }
        
        // 格式化成绩值
        vo.setFormattedScoreValue(competitionScoreService.formatScoreValue(score.getScoreValue(), score.getScoreType()));
        
        return vo;
    }
}
